﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;

using FinalProject.BL;
using System.Windows.Data;
using System.Collections;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Text.RegularExpressions;
using System.Windows.Input;
using FinalProject.DAL.Model;

namespace FinalProject.UI.Controls
{

    public class EditableItemGrid : System.Windows.Controls.DataGrid
    {
        public DataGridTextColumn colItemId;
        public DataGridComboBoxColumn colItemCode;
        public DataGridTextColumn colItemDescrip;
        public DataGridTextColumn colWarehouse;
        public DataGridTextColumn colQuanlity;
        public DataGridTextColumn colPrice;
        public DataGridTextColumn colVATRate;
        public DataGridTextColumn colTotalAmount;

        public EditableItemGrid()
            : base()
        {
            this.SelectionUnit = DataGridSelectionUnit.FullRow;
            this.SelectionMode = DataGridSelectionMode.Single;
            this.CanUserAddRows = true;
            this.AutoGenerateColumns = false;
            this.CanSelectMultipleItems = false;
            this.SelectionUnit = DataGridSelectionUnit.Cell;
            this.SelectedValuePath = "EditableItemGridEntry";
            InitializeComponent();
            this.InitializeEvent();

        }

        private void InitializeComponent()
        {
            colItemId = new DataGridTextColumn()
            {
                Header = "rowId",
                Binding = new Binding("Id"),
                Visibility = System.Windows.Visibility.Hidden
            };
            this.Columns.Add(colItemId);

            colItemCode = new DataGridComboBoxColumn()
            {
                Header = "Item",
                Width = 100,
            };
            this.Columns.Add(colItemCode);

            colWarehouse = new DataGridTextColumn()
            {
                Header = "Warehouse",
                Binding = new Binding("WarehouseCode"),
                IsReadOnly = true,
                Width = 100
            };
            this.Columns.Add(colWarehouse);

            colQuanlity = new DataGridTextColumn()
            {
                Header = "Quantity",
                Binding = new Binding("Quantity"),
                IsReadOnly = false,
                Width = 100
            };
            this.Columns.Add(colQuanlity);

            colPrice = new DataGridTextColumn()
            {
                Header = "Price",
                Binding = new Binding("UnitPrice"),
                Width = 100,
                IsReadOnly = true
            };
            this.Columns.Add(colPrice);

            colTotalAmount = new DataGridTextColumn()
            {
                Header = "Total Amount",
                Binding = new Binding("TotalAmount"),
                IsReadOnly = true,
                Width = 150
            };
            this.Columns.Add(colTotalAmount);

            colItemDescrip = new DataGridTextColumn()
            {
                Header = "Description",
                Binding = new Binding("Description"),
                Width = 250,
            };
            this.Columns.Add(colItemDescrip);

        }

        public void ClearData()
        {
            this.ItemsSource = new List<DocumentRow>();
        }

        public bool IsValidData()
        {
            bool result = true;
            for (int i = 0; i < this.Items.Count; i++)
            {
                DocumentRow entry = this.Items[i] as DocumentRow;
                if (entry != null && entry.ItemId != Guid.Empty)
                {
                    if (entry.Quantity == 0)
                    {
                        result = false;
                        Utilities.GetMessageWarning("Item must have quantity");
                    }
                }
            }
            return result;
        }

        public void LoadData(Guid orderId)
        {
            this.ItemsSource = OrderManagementBL.LoadAllRow(orderId);
            for (int i = 0; i < this.Items.Count; i++)
            {
                DocumentRow row = this.Items[i] as DocumentRow;
                if (row == null) continue;

                DataGridCell cellItem = this.GetCell(i, colItemCode.DisplayIndex);
                cellItem.Content = row.Item.Name;

                DataGridCell clWarehouse = this.GetCell(i, colWarehouse.DisplayIndex);
                clWarehouse.Content = ItemBL.GetWarehouseCodeById(row.ItemId);

            }
        }

        public IList<DocumentRow> GetAllEntry()
        {
            if (this.Items.IsNullOrEmpty()) return null;

            IList<DocumentRow> result = new List<DocumentRow>();

            for (int i = 0; i < this.Items.Count; i++)
            {
                DocumentRow item = this.Items[i] as DocumentRow;
                if (item != null)
                {
                    if (item.ItemId != Guid.Empty)
                        result.Add(item);
                }
            }
            return result;
        }

        public decimal GetTotalAmount()
        {
            if (this.Items.IsNullOrEmpty()) return decimal.Zero;

            decimal result = decimal.Zero;

            for (int i = 0; i < this.Items.Count; i++)
            {
                DocumentRow item = this.Items[i] as DocumentRow;
                if (item != null)
                {
                    if (item.ItemId != Guid.Empty)
                        result += item.TotalAmount ?? decimal.Zero;
                }
            }
            return result;
        }

        #region Events

        public delegate void GridChangedHandler(object sender, EventArgs e);

        public event GridChangedHandler GridValueChaged;

        private void OnGridChanged(object sender, EventArgs e)
        {
            if (GridValueChaged != null)
            {
                this.GridValueChaged(sender, e);
            }
        }

        private void InitializeEvent()
        {
            this.Initialized += EditableItemGrid_Initialized;
        }

        void EditableItemGrid_Initialized(object sender, EventArgs e)
        {
            System.Windows.Style comboStyle = new System.Windows.Style(typeof(ComboBox));
            System.Windows.EventSetter selectedChanged = new System.Windows.EventSetter(ComboBox.SelectionChangedEvent, new SelectionChangedEventHandler(CmbItems_SelectionChanged));
            comboStyle.Setters.Add(selectedChanged);
            colItemCode.EditingElementStyle = comboStyle;

            colItemCode.ItemsSource = OrderManagementBL.GetValueForItemCombobox();
            colItemCode.SelectedValuePath = "Key";
            colItemCode.DisplayMemberPath = "Value";
            colItemCode.SelectedValueBinding = new Binding("Key");

            System.Windows.Style textStyle = new System.Windows.Style(typeof(TextBox));
            System.Windows.EventSetter previewTextInput = new System.Windows.EventSetter(TextBox.PreviewTextInputEvent, new TextCompositionEventHandler(Quantity_TextPreview));
            System.Windows.EventSetter textChangeEvent = new System.Windows.EventSetter(TextBox.TextChangedEvent, new TextChangedEventHandler(Quantity_TextChanged));
            textStyle.Setters.Add(previewTextInput);
            textStyle.Setters.Add(textChangeEvent);
            //colQuanlity.Binding = new Binding("Text");
            colQuanlity.EditingElementStyle = textStyle;
        }

        private void Quantity_TextChanged(object sender, TextChangedEventArgs e)
        {

            TextBox txtControl = sender as TextBox;
            if (txtControl == null) return;

            if (!string.IsNullOrEmpty(txtControl.Text))
            {
                int quantity = Convert.ToInt32(txtControl.Text);
                DocumentRow selectedItem = this.CurrentCell.Item as DocumentRow;
                if (ItemBL.IsInStock(selectedItem.ItemId, quantity))
                {
                    selectedItem.TotalAmount = quantity * selectedItem.UnitPrice;
                    selectedItem.Quantity = quantity;

                    int rowIndex = this.Items.IndexOf(selectedItem);

                    DataGridCell cellTotal = this.GetCell(rowIndex, colTotalAmount.DisplayIndex);
                    cellTotal.Content = selectedItem.TotalAmount;
                }
                else
                {
                    Utilities.GetMessageWarning("Out of stock");
                    txtControl.Text = Convert.ToString(0);
                }
                OnGridChanged(this, EventArgs.Empty);
            }
        }

        private void Quantity_TextPreview(object sender, TextCompositionEventArgs e)
        {
            string strInput = e.Text;

            bool valid = Regex.IsMatch(strInput, @"^\d$");
            if (!valid)
            {
                e.Handled = true;
            }

        }

        private void CmbItems_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox control = sender as ComboBox;
            if (control == null) return;
            Guid itemId = control.SelectedValue.ToGuid();
            DocumentRow selectedItem = this.CurrentCell.Item as DocumentRow;
            ArrayList lstBinding = ItemBL.GetAllDataForEditGrid(itemId);
            if (lstBinding.IsNullOrEmpty()) return;
            int rowIndex = this.Items.IndexOf(selectedItem);
            selectedItem.ItemId = itemId;
            //selectedItem.WarehouseCode = lstBinding[0].ToString();
            //selectedItem.WarehouseId = lstBinding[1].ToGuid();
            selectedItem.UnitPrice = (decimal)lstBinding[2];

            DataGridCell clWarehouse = this.GetCell(rowIndex, colWarehouse.DisplayIndex);
            clWarehouse.Content = ItemBL.GetWarehouseCodeById(itemId);

            DataGridCell clPrice = this.GetCell(rowIndex, colPrice.DisplayIndex);
            clPrice.Content = selectedItem.UnitPrice;

            OnGridChanged(this, EventArgs.Empty);
        }

        #endregion
    }
}
